//
// Created by Felix on 24-4-26.
//

#ifndef GAZE_AUTHINTERCEPTOR_HPP
#define GAZE_AUTHINTERCEPTOR_HPP

#include "oatpp/web/server/interceptor/RequestInterceptor.hpp"
#include "oatpp/web/server/HttpRouter.hpp"
#include "oatpp/web/server/handler/AuthorizationHandler.hpp"

#include "handler/AuthHandler.hpp"

/**
 * 登陆认证
 */
class AuthInterceptor : public oatpp::web::server::interceptor::RequestInterceptor {
private:
    AuthHandler iAuthHandler;
    oatpp::web::server::HttpRouterTemplate<bool> authEndpoints;
public:
    AuthInterceptor() {
        // 不需要登陆接口
        authEndpoints.route("POST", "/hello", false);
        authEndpoints.route("POST", "/api/auth/sign_in", false);
        authEndpoints.route("GET", "/api/auth/sign_out", false);

        authEndpoints.route("GET", "/swagger/*", false);
        authEndpoints.route("GET", "/api-docs/oas-3.0.0.json", false);
    }

    std::shared_ptr <AuthInterceptor::OutgoingResponse> intercept(
            const std::shared_ptr <IncomingRequest> &request
    ) override {
        // 不需要认证直接放行
        auto r = authEndpoints.getRoute(
                request->getStartingLine().method, request->getStartingLine().path
        );
        if (r && !r.getEndpoint()) {
            return nullptr; // Continue without Authorization
        }

        // 需要登陆，查询用户是否存在
        auto authHeader = request->getHeader(oatpp::web::protocol::http::Header::AUTHORIZATION);
        auto authObject = std::static_pointer_cast<AuthHandler::Payload>(iAuthHandler.authorize(authHeader));
        // 用户存在直接放行
        if (authObject && authObject->userId) {
            // 把查询到的userId写入到请求的数据中，方便controller中使用
            // controller 通过 ENDPOINT("GET", "/api/users/current", getCurrentUser,BUNDLE(Int32, userId))中的BUNDLE进行获取
            request->putBundleData("userId", authObject->userId);
            return nullptr; // Continue - token is valid.
        }
        // 不存在报401错误
        throw oatpp::web::protocol::http::HttpError(oatpp::web::protocol::http::Status::CODE_401, "Unauthorized", {});
    }
};

#endif //GAZE_AUTHINTERCEPTOR_HPP
